﻿using Microsoft.Xna.Framework;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Terraria;
using TerrariaApi.Server;
using TShockAPI;
using TShockAPI.Hooks;

namespace BeanPoints
{
    [ApiVersion(2,1)]
    public class Main : TerrariaPlugin
    {
        
        public Main(Terraria.Main game) : base(game)
        {
        }
        #region --插件信息--
        public override string Name => "BeanPoints";
        public override Version Version => new Version(2,0,3);
        public override string Author => "豆沙";
        public override string Description => "A economics api";
        #endregion
        #region --路径组--
        public static List<BPNPC> npcs = new List<BPNPC>();
        #endregion
        public override void Initialize()
        {
            #region --加载配置文件--
            ConfigUtils.ReadConfig();
            #endregion
            ServerApi.Hooks.ServerJoin.Register(this,OnJoin);
            ServerApi.Hooks.GamePostInitialize.Register(this,OnInitialize);
            ServerApi.Hooks.NpcKilled.Register(this,OnNpcKilled);
            ServerApi.Hooks.NpcStrike.Register(this,OnNPCStrike);
            Commands.ChatCommands.Add(new Command("eco.user",eco,"eco"));
            Commands.ChatCommands.Add(new Command("eco.admin", ecoadmin, "ecoadmin"));
        }
        private void ecoadmin(CommandArgs args)
        {
            if (args.Parameters.Count<1)
            {
                args.Player.SendErrorMessage("输入/ecoadmin help查看更多");
                return;
            }
            var bplr_main = DBManager.GetPlayer(args.Player.Name);
            BeanPlayer bplr=null;
            TSPlayer tsplr=null;
            int count;
            switch (args.Parameters[0])
            {
                case "reload":
                    ConfigUtils.ReadConfig();
                    bplr_main.SendInfoMessage("重载成功");
                    break;
                case "addvalue":
                    int mobid;
                    int value;
                    if (int.TryParse(args.Parameters[1], out mobid) && int.TryParse(args.Parameters[2], out value))
                    {
                        if (mobid >= -65 && value >= 0)
                        {
                            if (ConfigUtils.monsterValue.ContainsKey(mobid))
                            {
                                ConfigUtils.monsterValue[mobid] = value;
                                bplr_main.SendSuccessMessage("修改成功");
                            }
                            else {
                                ConfigUtils.monsterValue.Add(mobid, value);
                                bplr_main.SendSuccessMessage("添加成功");
                            }
                            ConfigUtils.WriteMobValue();//修改本地怪物价值配置文件
                        }
                        else {
                            bplr_main.SendErrorMessage("请输入正确的数值,价值不可是负数,怪物ID不能小于-65");
                        }
                    }
                    else {
                        bplr_main.SendErrorMessage("请输入数字");
                    }
                    break;
                case "give":
                    bplr = DBManager.GetPlayerNoTP(args.Parameters[1]);
                    if (TSPlayer.FindByNameOrID(bplr.Name).Count!=0)
                    {
                        tsplr = TSPlayer.FindByNameOrID(bplr.Name)[0];
                    }
                    if (bplr==null)
                    {
                        bplr_main.SendErrorMessage("未找到该玩家");
                        return;
                    }
                    if (tsplr!=null)
                    {
                        bplr.Player = tsplr;
                    }
                    if (int.TryParse(args.Parameters[2], out count)&&count>=0)
                    {
                        bplr.AddPoints(count);
                        if (tsplr != null && tsplr.Active)
                        {
                            bplr.SendInfoMessage($"管理员给予了你  {count} {ConfigUtils.config.CurrencyName}");
                        }
                        bplr_main.SendSuccessMessage($"成功给予玩家 [{bplr.Name}]  {count}{ConfigUtils.config.CurrencyName}");
                        bplr.ShowChangeInfo(ChangeType.收入,count);
                    }
                    else {
                        bplr_main.SendErrorMessage("请输入正确数值(非负或非中文)");
                    }
                    break;
                case "take":
                    bplr = DBManager.GetPlayerNoTP(args.Parameters[1]);
                    if (TSPlayer.FindByNameOrID(bplr.Name).Count != 0)
                    {
                        tsplr = TSPlayer.FindByNameOrID(bplr.Name)[0];
                    }
                    if (bplr == null)
                    {
                        bplr_main.SendErrorMessage("未找到该玩家");
                        return;
                    }
                    if (tsplr != null)
                    {
                        bplr.Player = tsplr;
                    }
                    if (int.TryParse(args.Parameters[2], out count) && count >= 0)
                    {
                        bplr.DecreasePoints(count);
                        if (tsplr!=null&&tsplr.Active)
                        {
                            bplr.SendInfoMessage($"管理员扣除了你  {count} {ConfigUtils.config.CurrencyName}");
                        }
                        bplr_main.SendSuccessMessage($"成功取走玩家 [{bplr.Name}]  {count}{ConfigUtils.config.CurrencyName}");
                        bplr.ShowChangeInfo(ChangeType.支出, count);
                    }
                    else
                    {
                        bplr_main.SendErrorMessage("请输入正确数值(非负或非中文)");
                    }
                    break;
                case "help":
                    bplr_main.SendMessage("/ecoadmin help 查看钱包帮助\n/ecoadmin addvalue [怪物ID] [金额] 添加怪物钱币数据进配置文件\n/ecoadmin give [玩家名] [金额] 给予玩家指定数额钱币\n/ecoadmin take [玩家名] [金额] 扣除指定玩家金额数\n/ecoadmin reload 重载配置文件", Color.DarkTurquoise);
                    break;
                default:
                    bplr_main.SendInfoMessage("输入/ecoadmin help 查看更多");
                    break;
            }
        }
        private void OnNPCStrike(NpcStrikeEventArgs args)
        {
            BPNPC npc;
            if (npcs.Exists(n => n.ID == args.Npc.whoAmI && n.RealNPC.type == args.Npc.type && n.RealNPC.lifeMax == args.Npc.lifeMax))
            {
                npc = npcs.Find(n => n.ID == args.Npc.whoAmI && n.RealNPC.type == args.Npc.type && n.RealNPC.lifeMax == args.Npc.lifeMax);
                if (!npc.TargetPlayers.Keys.Contains(args.Player.name))
                {
                    npc.AddDamage(args.Player.name, (float)args.Damage);
                }
                else
                {
                    npc.AddDamage(args.Player.name, (float)args.Damage);
                }
            }
            else {
                npc = new BPNPC(args.Npc.whoAmI, args.Npc);
                npc.AddDamage(args.Player.name, (float)args.Damage);
                npcs.Add(npc);
            }
        }
        private void OnNpcKilled(NpcKilledEventArgs args)
        {
            BPNPC npc;
            if (npcs.Exists(n => n.ID == args.npc.whoAmI && n.RealNPC.type == args.npc.type && n.RealNPC.lifeMax == args.npc.lifeMax))
            {
                npc = npcs.Find(n => n.ID == args.npc.whoAmI && n.RealNPC.type == args.npc.type && n.RealNPC.lifeMax == args.npc.lifeMax);

                if (ConfigUtils.config.EnableMonstersDrop==false)
                {
                    npc.ClearCoins(8);
                }
                npc.Conclude();
                npc.CheckDead(ref npcs);
            }
        }

        private void eco(CommandArgs args)
        {
            if (args.Parameters.Count<1)
            {
                args.Player.SendInfoMessage("输入/eco help 查看更多");
                return;
            }
            var plr = DBManager.GetPlayer(args.Player.Name);
            switch (args.Parameters[0])
            {
                case "help":
                    plr.SendMessage("/eco help 查看钱包帮助\n/eco me 查看个人钱包\n/eco pay [玩家名] [金额] 向玩家支付\n/eco ex 将物品货币存为虚拟货币\n/eco aq [金额] 将虚拟货币存为物品货币", Color.DarkTurquoise);
                    break;
                case "me":
                    plr.SendMessage($"——[个人信息]——\nID:{plr.Name}\n{ConfigUtils.config.CurrencyName}:{plr.Points}\n————————",Color.Tomato);
                    break;
                case "pay":
                    var payplr = DBManager.GetPlayerNoTP(args.Parameters[1]);
                    if (payplr == null)
                    {
                        plr.SendErrorMessage("未找到指定玩家");
                        return;
                    }
                    int paycount;
                    if (int.TryParse(args.Parameters[2], out paycount)&&paycount>=0)
                    {
                        if (paycount <= plr.Points)
                        {
                            payplr.AddPoints(paycount);
                            if (TSPlayer.FindByNameOrID(payplr.Name).Count!=0)
                            {
                                payplr.Player = TSPlayer.FindByNameOrID(payplr.Name)[0];
                                payplr.ShowChangeInfo(ChangeType.收入, paycount);
                                payplr.SendInfoMessage($"[{plr.Name}] 向你转入 {paycount} {ConfigUtils.config.CurrencyName}");
                            }  
                            plr.DecreasePoints(paycount);
                            plr.ShowChangeInfo(ChangeType.支出,paycount);
                            plr.SendSuccessMessage($"成功向[{payplr.Name}]转出{paycount}{ConfigUtils.config.CurrencyName}");
                        }
                        else {
                            plr.SendErrorMessage("请确保你有足够的金额");
                        }
                    }
                    else {
                        plr.SendErrorMessage("请输入正确的支付金额(非负或非中文)");
                    }
                    break;
                case "ex":
                    if (ConfigUtils.config.AllowCoinsExchange==false)
                    {
                        plr.SendErrorMessage("兑换系统未开启,请去配置文件开启");
                        return;
                    }
                    int stack = args.Player.TPlayer.trashItem.stack;
                    int count=0;
                    if (args.Player.TPlayer.trashItem.netID == 0)
                    {
                        plr.SendInfoMessage("请将要兑换的钱币放进垃圾桶后输入指令");
                        return;
                    }
                    else if (args.Player.TPlayer.trashItem.netID == Terraria.ID.ItemID.CopperCoin)
                    {
                        if (ConfigUtils.config.CoinValue["Copper"] != 0)
                        {
                            count = ConfigUtils.config.CoinValue["Copper"] * stack;
                        }
                        else {
                            plr.SendErrorMessage("铜币的价值为0，无法兑换成虚拟货币");
                            return;
                        }
                    }
                    else if (args.Player.TPlayer.trashItem.netID == Terraria.ID.ItemID.SilverCoin)
                    {
                        if (ConfigUtils.config.CoinValue["Silver"] != 0)
                        {
                            count = ConfigUtils.config.CoinValue["Silver"] * stack;
                        }
                        else
                        {
                            plr.SendErrorMessage("银币的价值为0，无法兑换成虚拟货币");
                            return;
                        }
                    }
                    else if (args.Player.TPlayer.trashItem.netID == Terraria.ID.ItemID.GoldCoin)
                    {
                        if (ConfigUtils.config.CoinValue["Gold"] != 0)
                        {
                            count = ConfigUtils.config.CoinValue["Gold"] * stack;
                        }
                        else
                        {
                            plr.SendErrorMessage("金币的价值为0，无法兑换成虚拟货币");
                            return;
                        }
                    }
                    else if (args.Player.TPlayer.trashItem.netID == Terraria.ID.ItemID.PlatinumCoin)
                    {
                        if (ConfigUtils.config.CoinValue["Platinum"] != 0)
                        {
                            count = ConfigUtils.config.CoinValue["Platinum"] * stack;
                        }
                        else
                        {
                            plr.SendErrorMessage("铂金币的价值为0，无法兑换成虚拟货币");
                            return;
                        }
                    }
                    else {
                        plr.SendErrorMessage("该物品无法兑换");
                        return;
                    }
                    plr.AddPoints(count);
                    plr.ShowChangeInfo(ChangeType.收入, count);
                    plr.SendInfoMessage($"成功兑换 {count} {ConfigUtils.config.CurrencyName}");
                    args.Player.TPlayer.trashItem.stack = 0;
                    plr.Player.SendData(PacketTypes.PlayerSlot, args.Player.TPlayer.trashItem.Name, args.Player.Index, 179, args.Player.TPlayer.trashItem.prefix);
                    break;
                case "aq":
                    if (ConfigUtils.config.AllowCoinsExchange == false)
                    {
                        plr.SendErrorMessage("兑换系统未开启,请去配置文件开启");
                        return;
                    }
                    int aimcount;
                    if (int.TryParse(args.Parameters[1], out aimcount))
                    {
                        plr.PriceIntoCoins(aimcount);
                    }
                    else {
                        plr.SendErrorMessage("请输入有效数字");
                    }
                    break;
                default:
                    plr.SendInfoMessage("输入/eco help 查看更多");
                    break;
            }
        }

        private void OnInitialize(EventArgs args)
        {
            DBManager.CreateTable();
        }

        private void OnJoin(JoinEventArgs args)
        {
            var players = DBManager.GetAllPlayers();
            BeanPlayer bplr;
            var plr = TShock.Players[args.Who];
            if (!players.Exists(p => p.Name == plr.Name))
            {
                bplr = new BeanPlayer(players.Count + 1, plr.Name, 0);
                DBManager.AddPlayer(bplr);
                TShock.Log.ConsoleInfo($"[BeanPoints]添加玩家 {plr.Name} 数据成功！");
            }
        }
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                ServerApi.Hooks.ServerJoin.Deregister(this, OnJoin);
                ServerApi.Hooks.GamePostInitialize.Deregister(this, OnInitialize);
                ServerApi.Hooks.NpcKilled.Deregister(this, OnNpcKilled);
                ServerApi.Hooks.NpcStrike.Deregister(this, OnNPCStrike);
            }
            base.Dispose(disposing);
        }
    }
}
